package com.ssyx.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ssyx.auth.AuthThreadLocal;
import com.ssyx.constant.GlobalConstant;
import com.ssyx.constant.RedisConstant;
import com.ssyx.exception.SsyxException;
import com.ssyx.mapper.AdminMapper;
import com.ssyx.model.acl.Admin;
import com.ssyx.result.ResultCodeEnum;
import com.ssyx.service.AdminService;
import com.ssyx.utils.JwtHelper;
import com.ssyx.utils.MD5;
import com.ssyx.vo.acl.AdminQueryVo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: ssyx-parent
 * @className: AdminServiceImpl
 * @description: 用户管理
 * @data: 2024/3/7 15:28
 * @author: ihu
 * @version: 1.0
 **/

@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
	
	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	
	@Override
	public IPage<Admin> selectPageUser(Page<Admin> pageParam, AdminQueryVo adminQueryVo) {
		return baseMapper.selectPage(pageParam,
				Wrappers.<Admin>lambdaQuery().eq(!StringUtils.isEmpty(adminQueryVo.getUsername()), Admin::getUsername,
						adminQueryVo.getUsername()).like(!StringUtils.isEmpty(adminQueryVo.getName()), Admin::getName,
						adminQueryVo.getName()));
	}
	
	@Override
	public void saveAdmin(Admin admin) {
		Admin adminInfo = getOne(Wrappers.<Admin>lambdaQuery().eq(Admin::getUsername, admin.getUsername()));
		if (adminInfo != null) {
			log.error("用户名已存在");
			throw new SsyxException(ResultCodeEnum.INFORMATION_EXIST);
		}
		// 对输入密码进行加密 MD5,设置到admin对象里面
		admin.setPassword(MD5.encrypt(admin.getPassword()));
		// 调用方法添加
		save(admin);
	}
	
	@Override
	public Map<String, String> login(Admin admin) {
		Map<String, String> map = new HashMap<>();
		Admin adminInfo = getOne(Wrappers.<Admin>lambdaQuery().eq(Admin::getUsername, admin.getUsername()));
		if (adminInfo == null) {
			log.error("用户名不存在");
			throw new SsyxException(ResultCodeEnum.USERNAME_ERROR);
		}
		if (!adminInfo.getPassword().equals(MD5.encrypt(admin.getPassword()))) {
			log.error("密码错误");
			throw new SsyxException(ResultCodeEnum.PASSWORD_ERROR);
		}
		String token = JwtHelper.createToken(adminInfo.getId(), adminInfo.getUsername());
		redisTemplate.opsForValue().set(RedisConstant.ADMIN_KEY_PREFIX + adminInfo.getId(), token,
				RedisConstant.SKUKEY_TIMEOUT, TimeUnit.DAYS);
		redisTemplate.opsForValue().set(RedisConstant.FEIGNCLIENT, GlobalConstant.VALIDATE,
				RedisConstant.KEY_TEMPORARY_TIMEOUT, TimeUnit.SECONDS);
		map.put("token", token);
		return map;
	}
	
	@Override
	public Map<String, Object> info() {
		Map<String, Object> adminInfo =
				(Map<String, Object>) redisTemplate.opsForValue().get(RedisConstant.ADMIN_LOGIN_KEY_PREFIX + AuthThreadLocal.getId());
		if (adminInfo != null) {
			return adminInfo;
		}
		Admin admin = getById(AuthThreadLocal.getId());
		if (admin == null) {
			log.error("获取用户信息失败");
			throw new SsyxException(ResultCodeEnum.FETCH_USERINFO_ERROR);
		}
		Map<String, Object> map = new HashMap<>();
		map.put("id", admin.getId());
		map.put("name", admin.getName());
		map.put("phone", admin.getPhone());
		map.put("ware_id", admin.getWareId());
		map.put("avatar", admin.getPhoto());
		map.put("role_name", admin.getRoleName());
		redisTemplate.opsForValue().set(RedisConstant.ADMIN_LOGIN_KEY_PREFIX + admin.getId(), map,
				RedisConstant.INFO_TIMEOUT, TimeUnit.DAYS);
		return map;
	}
	
	@Override
	public void updateAdmin(Admin admin) {
		Admin adminInfo = getOne(Wrappers.<Admin>lambdaQuery().eq(Admin::getUsername, admin.getUsername()));
		if (adminInfo == null) {
			log.error("用户名不存在");
			throw new SsyxException(ResultCodeEnum.USERNAME_ERROR);
		}
		admin.setPassword(MD5.encrypt(admin.getPassword()));
		updateById(admin);
		redisTemplate.delete(RedisConstant.ADMIN_KEY_PREFIX + adminInfo.getId());
		redisTemplate.delete((RedisConstant.ADMIN_LOGIN_KEY_PREFIX + adminInfo.getId()));
	}
}
